
<!DOCTYPE html>
<html lang="en">
    <head>

    <title>FAQ — XLua</title>
    <meta charset="utf-8">
    <meta name="description" content="XLua">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

    <link rel="stylesheet" href="/xLua/public/css/page.css">

    <script src="/xLua/public/js/vue.js"></script>
    <script src="/xLua/public/js/jquery.js"></script>
    </head>

    <body>
        
            <nav class="nav">
    <div class="border">
        <img src="/xLua/public/images/logo.png" />
        <button class="hiden-in-phone">V2.1</button>
        <button id="btn-menu" class="hiden-in-pc">菜单</button>
        <ul class="nav-link hiden-in-phone">
            <!--li>
                <form id="search-form">
                    <input type="text" id="search-query" class="search-query">
                </form>
            </li!-->
            <li><a href="https://github.com/Tencent/xLua" class="nav-link-li">下载项目</a></li>
            <li><a href="/xLua/public/v1/guide/use.html" class="nav-link-li">使用案例</a></li>
            <li><a href="/xLua/public/v1/guide/version.html" class="nav-link-li">更新记录</a></li>
            <li><a href="/xLua/public/v1/guide/contribution.html" class="nav-link-li">贡献指南</li>
            <li><a href="/xLua/public/v1/guide/index.html" class="nav-link-li">教程</a></li>
            <li><a href="/xLua/public/" class="nav-link-li current">首页</a></li>
        </ul>
    </div>
</nav>

<div id="container" class="container clear">
    <section class="sidebar clearfix">
    <ul>
        
            
            
                <li><h3>基础</h3></li>
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/index.html" class="sidebar-link">介绍</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/version.html" class="sidebar-link">更新记录</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/use.html" class="sidebar-link">商业案例</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/faq.html" class="sidebar-link current">FAQ</a></p>
            </li>
        
            
            
            
                <li><h3>教程</h3></li>
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/tutorial.html" class="sidebar-link">从零开始</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/configure.html" class="sidebar-link">XLua的配置</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/api.html" class="sidebar-link">C# API</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/crtdel-3rd.html" class="sidebar-link">添加删除第三方库</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/gc-optimization.html" class="sidebar-link">GC优化指南</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/performance-analysis.html" class="sidebar-link">性能分析工具</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/signature.html" class="sidebar-link">数字签名</a></p>
            </li>
        
            
            
            
            
                <li><h3>其他</h3></li>
            
            <li>
                <p><a href="/xLua/public/v1/guide/hotfix.html" class="sidebar-link">热标识</a></p>
            </li>
        
            
            
            
            
            <li>
                <p><a href="/xLua/public/v1/guide/features.html" class="sidebar-link">特性</a></p>
            </li>
        
    </ul>
</section>
    <article class="clearfix">
    <h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="xLua发布包怎么用？"><a href="#xLua发布包怎么用？" class="headerlink" title="xLua发布包怎么用？"></a>xLua发布包怎么用？</h3><p>xLua目前以zip包形式发布，在工程目录下解压即可。</p>
<h3 id="xLua可以放别的目录吗？"><a href="#xLua可以放别的目录吗？" class="headerlink" title="xLua可以放别的目录吗？"></a>xLua可以放别的目录吗？</h3><p>可以，但生成代码目录需要配置一下（默认放<code>Assets\XLua\Gen</code>目录），具体可以看《XLua的配置.doc》的GenPath配置介绍。</p>
<h3 id="lua源码只能以txt后缀？"><a href="#lua源码只能以txt后缀？" class="headerlink" title="lua源码只能以txt后缀？"></a>lua源码只能以txt后缀？</h3><p>什么后缀都可以。</p>
<p>如果你想以<code>TextAsset</code>打包到安装包（比如放到<code>Resources</code>目录），Unity不认<code>lua</code>后缀，这是Unity的规则。</p>
<p>如果你不打包到安装包，就没有后缀的限制：比如自行下载到某个目录（这也是热更的正确姿势），然后通过CustomLoader或者设置package.path去读这个目录。</p>
<p>那为啥xLua本身带的lua源码（包括示例）为什么都是txt结尾呢？因为xLua本身就一个库，不含下载功能，也不方便运行时去某个地方下载代码，通过TextAsset是较简单的方式。</p>
<h3 id="Plugins源码在哪里可以找到，怎么使用？"><a href="#Plugins源码在哪里可以找到，怎么使用？" class="headerlink" title="Plugins源码在哪里可以找到，怎么使用？"></a>Plugins源码在哪里可以找到，怎么使用？</h3><p>Plugins源码位于<code>xLua_Project_Root/build</code>下。</p>
<p>源码编译依赖cmake，安装cmake后执行make_xxxx_yyyy.zz即可，xxxx代表平台，比如ios，android等，yyyy是要集成的虚拟机，有lua53和luajit两者，zz是后缀，windows下是bat，其它平台是sh。</p>
<p>windows编译依赖Visual Studio 2015。</p>
<p>android编译在linux下执行，依赖NDK，并且需要把脚本中ANDROID_NDK指向NDK的安装目录。</p>
<p>ios和osx需要在mac下编译。</p>
<h3 id="报类似“xlua-access-no-field-Hitfix0-Update”的错误怎么解决？"><a href="#报类似“xlua-access-no-field-Hitfix0-Update”的错误怎么解决？" class="headerlink" title="报类似“xlua.access, no field __Hitfix0_Update”的错误怎么解决？"></a>报类似“xlua.access, no field __Hitfix0_Update”的错误怎么解决？</h3><p>按<a href="hotfix.html">Hotfix操作指南</a>一步步操作。</p>
<h3 id="报“please-install-the-Tools”"><a href="#报“please-install-the-Tools”" class="headerlink" title="报“please install the Tools”"></a>报“please install the Tools”</h3><p>没有把Tools安装到Assets平级目录，安装包，或者master下都能找到这个目录。</p>
<h3 id="报“This-delegate-interface-must-add-to-CSharpCallLua-XXX”异常怎么解决？"><a href="#报“This-delegate-interface-must-add-to-CSharpCallLua-XXX”异常怎么解决？" class="headerlink" title="报“This delegate/interface must add to CSharpCallLua : XXX”异常怎么解决？"></a>报“This delegate/interface must add to CSharpCallLua : XXX”异常怎么解决？</h3><p>在编辑器下xLua不生成代码都可以运行，出现这种提示，要么是该类型没加CSharpCallLua，要么是加之前生成过代码，没重新执行生成。</p>
<p>解决办法，确认XXX（类型名）加上CSharpCallLua后，清除代码后运行。</p>
<h3 id="hotfix下怎么触发一个event"><a href="#hotfix下怎么触发一个event" class="headerlink" title="hotfix下怎么触发一个event"></a>hotfix下怎么触发一个event</h3><p>首先通过xlua.private_accessible开启私有成员访问。</p>
<p>跟着通过对象的”&amp;事件名”字段调用delegate，例如self[‘&amp;MyEvent’]()，其中MyEvent是事件名。</p>
<h3 id="怎么对Unity-Coroutine的实现函数打补丁？"><a href="#怎么对Unity-Coroutine的实现函数打补丁？" class="headerlink" title="怎么对Unity Coroutine的实现函数打补丁？"></a>怎么对Unity Coroutine的实现函数打补丁？</h3><p>见<a href="hotfix.html">Hotfix操作指南</a>相应章节。</p>
<h3 id="支持NGUI（或者UGUI-DOTween等等）么？"><a href="#支持NGUI（或者UGUI-DOTween等等）么？" class="headerlink" title="支持NGUI（或者UGUI/DOTween等等）么？"></a>支持NGUI（或者UGUI/DOTween等等）么？</h3><p>支持，xLua最主要的特性是让你原来用C#写的地方可以换成用lua写，你C#能用的插件，基本都能用。</p>
<h3 id="如果需要调试，CustomLoader的filepath参数该如何处理？"><a href="#如果需要调试，CustomLoader的filepath参数该如何处理？" class="headerlink" title="如果需要调试，CustomLoader的filepath参数该如何处理？"></a>如果需要调试，CustomLoader的filepath参数该如何处理？</h3><p>lua里头调用require ‘a.b’时，CustomLoader会被调用，并传入字符串”a.b”，你需要理解这字符串，（从文件/内存/网络等）加载好lua文件，返回两个东西，第一个是调试器可以理解的路径，比如：a/b.lua，这个通过设置ref类型的filepath参数返回，第二个是UTF8格式的源码的字节流（byte[]），通过返回值返回。</p>
<h3 id="什么是生成代码？"><a href="#什么是生成代码？" class="headerlink" title="什么是生成代码？"></a>什么是生成代码？</h3><p>xLua支持的lua和C#间交互技术之一，这种技术通过生成两者间的适配代码来实现交互，性能较好，是推荐的方式。</p>
<p>另一种交互技术是反射，这种方式对安装包的影响更少，可以在性能要求不高或者对安装包大小很敏感的场景下使用。</p>
<h3 id="改了接口后，之前生成的代码出现错误怎么办？"><a href="#改了接口后，之前生成的代码出现错误怎么办？" class="headerlink" title="改了接口后，之前生成的代码出现错误怎么办？"></a>改了接口后，之前生成的代码出现错误怎么办？</h3><p>清除掉生成代码（执行“Clear Generated Code”菜单，如果你重启过，会找不到这个菜单，这时你可以手动删除整个生成代码目录），等编译完成后重新生成。</p>
<h3 id="应该什么时候生成代码？"><a href="#应该什么时候生成代码？" class="headerlink" title="应该什么时候生成代码？"></a>应该什么时候生成代码？</h3><p>开发期不建议生成代码，可以避免很多由于不一致导致的编译失败，以及生成代码本身的编译等待。</p>
<p>build手机版本前必须执行生成代码，建议做成自动化的。</p>
<p>做性能调优，性能测试前必须执行生成代码，因为生成和不生成性能的区别还是很大的。</p>
<h3 id="CS名字空间下有所有C-API是不是很占内存？"><a href="#CS名字空间下有所有C-API是不是很占内存？" class="headerlink" title="CS名字空间下有所有C# API是不是很占内存？"></a>CS名字空间下有所有C# API是不是很占内存？</h3><p>由于用了lazyload，这个“有”只是个虚拟的概念，比如UnityEngine.GameObject，是访问第一次CS.UnityEngine.GameObject或者第一个实例往lua传送才加载该类型方法，属性等。</p>
<h3 id="LuaCallSharp以及CSharpCallLua两种生成各在什么场景下用？"><a href="#LuaCallSharp以及CSharpCallLua两种生成各在什么场景下用？" class="headerlink" title="LuaCallSharp以及CSharpCallLua两种生成各在什么场景下用？"></a>LuaCallSharp以及CSharpCallLua两种生成各在什么场景下用？</h3><p>看调用者和被调用者，比如要在lua调用C#的GameObject.Find函数，或者调用gameobject的实例方法，属性等，GameObject类要加LuaCallSharp，而想把一个lua函数挂到UI回调，这是调用者是C#，被调用的是一个lua函数，所以回调声明的delegate要加CSharpCallLua。</p>
<p>有时会比较迷惑人，比如<code>List&lt;int&gt;.Find(Predicate&lt;int&gt; match)</code>的调用，<code>List&lt;int&gt;</code>当然是加LuaCallSharp，而<code>Predicate&lt;int&gt;</code>却要加CSharpCallLua，因为match的调用者在C#，被调用的是一个lua函数。</p>
<p>更无脑一点的方式是看到“This delegate/interface must add to CSharpCallLua : XXX”，就把XXX加到CSharpCallLua即可。</p>
<h3 id="值类型传递会有gc-alloc么？"><a href="#值类型传递会有gc-alloc么？" class="headerlink" title="值类型传递会有gc alloc么？"></a>值类型传递会有gc alloc么？</h3><p>如果你使用的是delegate调用lua函数，或者用LuaTable、LuaFunction的无gc接口，或者数组的话，以下值类型都是没gc的：</p>
<p>1、所有的基本值类型（所有整数，所有浮点数，decimal）；</p>
<p>2、所有的枚举类型；</p>
<p>3、字段只包含值类型的struct，可嵌套其它只包含值类型struct；</p>
<p>其中2、3需要把该类型加到GCOptimize。</p>
<h3 id="反射在ios下可用吗？"><a href="#反射在ios下可用吗？" class="headerlink" title="反射在ios下可用吗？"></a>反射在ios下可用吗？</h3><p>ios下的限制有两个：1、没有jit；2、代码剪裁（stripping）；</p>
<p>对于C#通过delegate或者interface调用lua，如果不生成代码是用反射的emit，这依赖jit，所以这目前只在编辑器可用。</p>
<p>对于lua调用C#，主要会被代码剪裁影响，这时你可以配置ReflectionUse（不要配LuaCallSharp），执行“Generate Code”，这时不会对该类生成封装代码，而是生成link.xml把该类配置为不剪裁。</p>
<p>简而言之，除了CSharpCallLua是必须的（这类生成代码往往不多），LuaCallSharp生成都可以改为用反射。</p>
<h3 id="支持泛化方法的调用么？"><a href="#支持泛化方法的调用么？" class="headerlink" title="支持泛化方法的调用么？"></a>支持泛化方法的调用么？</h3><p>不直接支持，但能调用到。如果是静态方法，可以自己写个封装来实例化泛化方法。</p>
<p>如果是成员方法，xLua支持扩展方法，你可以添加一个扩展方法来实例化泛化方法。该扩展方法使用起来就和普通成员方法一样。</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><div class="line"><span class="comment">// C#</span></div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Button <span class="title">GetButton</span>(<span class="params"><span class="keyword">this</span> GameObject go</span>)</span></div><div class="line">&#123;</div><div class="line">    <span class="keyword">return</span> go.GetComponent&lt;Button&gt;();</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight lua"><table><tr><td class="code"><pre><div class="line"><span class="comment">-- lua</span></div><div class="line"><span class="keyword">local</span> go = CS.UnityEngine.GameObject.Find(<span class="string">"button"</span>)</div><div class="line">go:GetButton().onClick:AddListener(<span class="function"><span class="keyword">function</span><span class="params">()</span></span></div><div class="line">    <span class="built_in">print</span>(<span class="string">'onClick'</span>)</div><div class="line"><span class="keyword">end</span>)</div></pre></td></tr></table></figure>
<h3 id="支持lua调用C-重载函数吗？"><a href="#支持lua调用C-重载函数吗？" class="headerlink" title="支持lua调用C#重载函数吗？"></a>支持lua调用C#重载函数吗？</h3><p>支持，但没有C#端支持的那么完善，比如重载方法void Foo(int a)和void Foo(short a)，由于int和short都对应lua的number，是没法根据参数判断调用的是哪个重载。这时你可以借助扩展方法来为其中一个起一个别名。</p>
<h3 id="编辑器下运行正常，打包的时候生成代码报“没有某方法-属性-字段定义”怎么办？"><a href="#编辑器下运行正常，打包的时候生成代码报“没有某方法-属性-字段定义”怎么办？" class="headerlink" title="编辑器下运行正常，打包的时候生成代码报“没有某方法/属性/字段定义”怎么办？"></a>编辑器下运行正常，打包的时候生成代码报“没有某方法/属性/字段定义”怎么办？</h3><p>往往是由于该方法/属性/字段是扩在条件编译里头，只在UNITY_EDITOR下有效，这是可以通过把这方法/属性/字段加到黑名单来解决，加了之后要等编译完成后重新执行代码生成。</p>
<h3 id="this-string-field-或者this-object-field-操作符重载为什么在lua无法访问？（比如Dictionary-lt-string-xxx-gt-Dictionary-lt-object-xxx-gt-在lua中无法通过dic-‘abc’-或者dic-abc检索值）"><a href="#this-string-field-或者this-object-field-操作符重载为什么在lua无法访问？（比如Dictionary-lt-string-xxx-gt-Dictionary-lt-object-xxx-gt-在lua中无法通过dic-‘abc’-或者dic-abc检索值）" class="headerlink" title="this[string field]或者this[object field]操作符重载为什么在lua无法访问？（比如Dictionary&lt;string, xxx&gt;, Dictionary&lt;object, xxx&gt;在lua中无法通过dic[‘abc’]或者dic.abc检索值）"></a>this[string field]或者this[object field]操作符重载为什么在lua无法访问？（比如<code>Dictionary&lt;string, xxx&gt;</code>, <code>Dictionary&lt;object, xxx&gt;</code>在lua中无法通过dic[‘abc’]或者dic.abc检索值）</h3><p>在2.1.5~2.1.6版本把这个特性去掉，因为：1、这个特性会导致基类定义的方法、属性、字段等无法访问（比如Animation无法访问到GetComponent方法）；2、key为当前类某方法、属性、字段的名字的数据无法检索，比如Dictionary类型，dic[‘TryGetValue’]返回的是一个函数，指向Dictionary的TryGetValue方法。</p>
<p>建议直接方法该操作符的等效方法，比如Dictionary的TryGetValue，如果该方法没有提供，可以在C#那通过Extension method封装一个使用。</p>
<h3 id="有的Unity对象，在C-为null，在lua为啥不为nil呢？比如一个已经Destroy的GameObject"><a href="#有的Unity对象，在C-为null，在lua为啥不为nil呢？比如一个已经Destroy的GameObject" class="headerlink" title="有的Unity对象，在C#为null，在lua为啥不为nil呢？比如一个已经Destroy的GameObject"></a>有的Unity对象，在C#为null，在lua为啥不为nil呢？比如一个已经Destroy的GameObject</h3><p>其实那C#对象并不为null，是UnityEngine.Object重载的==操作符，当一个对象被Destroy，未初始化等情况，obj == null返回true，但这C#对象并不为null，可以通过System.Object.ReferenceEquals(null, obj)来验证下。</p>
<p>对应这种情况，可以为UnityEngine.Object写一个扩展方法：</p>
<figure class="highlight csharp"><table><tr><td class="code"><pre><div class="line">[<span class="meta">LuaCallCSharp</span>]</div><div class="line">[<span class="meta">ReflectionUse</span>]</div><div class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> <span class="title">UnityEngineObjectExtention</span></div><div class="line">&#123;</div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">bool</span> <span class="title">IsNull</span>(<span class="params"><span class="keyword">this</span> UnityEngine.Object o</span>) <span class="comment">// 或者名字叫IsDestroyed等等</span></span></div><div class="line">    &#123;</div><div class="line">        <span class="keyword">return</span> o == <span class="literal">null</span>;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>然后在lua那你对所有UnityEngine.Object实例都使用IsNull判断</p>
<figure class="highlight lua"><table><tr><td class="code"><pre><div class="line"><span class="built_in">print</span>(go:GetComponent(<span class="string">'Animator'</span>):IsNull())</div></pre></td></tr></table></figure>
<h3 id="泛型实例怎么构造"><a href="#泛型实例怎么构造" class="headerlink" title="泛型实例怎么构造"></a>泛型实例怎么构造</h3><p>涉及的类型都在mscorlib，Assembly-CSharp程序集的话，泛型实例的构造和普通类型是一样的，都是CS.namespace.typename()，可能比较特殊的是typename的表达，泛型实例的typename的表达包含了标识符非法符号，最后一部分要换成[“typename”]，以<code>List&lt;string&gt;</code>为例</p>
<figure class="highlight lua"><table><tr><td class="code"><pre><div class="line"><span class="keyword">local</span> lst = CS.System.Collections.Generic[<span class="string">"List`1[System.String]"</span>]()</div></pre></td></tr></table></figure>
<p>如果某个泛型实例的typename不确定，可以在C#测打印下typeof(不确定的类型).ToString()</p>
<p>如果涉及mscorlib，Assembly-CSharp程序集之外的类型的话，可以用C#的反射来做：</p>
<figure class="highlight lua"><table><tr><td class="code"><pre><div class="line"><span class="keyword">local</span> dic = CS.System.Activator.CreateInstance(CS.System.Type.GetType(<span class="string">'System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UnityEngine.Vector3, UnityEngine]],mscorlib'</span>))</div><div class="line">dic:Add(<span class="string">'a'</span>, CS.UnityEngine.Vector3(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>))</div><div class="line"><span class="built_in">print</span>(dic:TryGetValue(<span class="string">'a'</span>))</div></pre></td></tr></table></figure>
<h3 id="调用LuaEnv-Dispose时，报“try-to-dispose-a-LuaEnv-with-C-callback-”错是什么原因？"><a href="#调用LuaEnv-Dispose时，报“try-to-dispose-a-LuaEnv-with-C-callback-”错是什么原因？" class="headerlink" title="调用LuaEnv.Dispose时，报“try to dispose a LuaEnv with C# callback!”错是什么原因？"></a>调用LuaEnv.Dispose时，报“try to dispose a LuaEnv with C# callback!”错是什么原因？</h3><p>这是由于C#还存在指向lua虚拟机里头某个函数的delegate，为了防止业务在虚拟机释放后调用这些无效（因为其引用的lua函数所在虚拟机都释放了）delegate导致的异常甚至崩溃，做了这个检查。</p>
<p>怎么解决？释放这些delegate即可，所谓释放，在C#中，就是没有引用：</p>
<p>你是在C#通过LuaTable.Get获取并保存到对象成员，赋值该成员为null；</p>
<p>你是在lua那把lua函数注册到一些事件事件回调，反注册这些回调；</p>
<p>如果你是通过xlua.hotfix(class, method, func)注入到C#，则通过xlua.hotfix(class, method, nil)删除；</p>
<p>要注意以上操作在Dispose之前完成。</p>
<h3 id="C-参数（或字段）类型是object时，传递整数默认是以long类型传递，如何指明其它类型？比如int"><a href="#C-参数（或字段）类型是object时，传递整数默认是以long类型传递，如何指明其它类型？比如int" class="headerlink" title="C#参数（或字段）类型是object时，传递整数默认是以long类型传递，如何指明其它类型？比如int"></a>C#参数（或字段）类型是object时，传递整数默认是以long类型传递，如何指明其它类型？比如int</h3><p>看<a href="https://github.com/Tencent/xLua/blob/master/Assets/XLua/Examples/11_RawObject/RawObjectTest.cs">例子11</a></p>

    <div class="footer">
        发现错误？想参与编辑？ 
        <a href="https://github.com/Tencent/xLua/tree/master/docs/source/src/v1/guide/faq.md" target="_blank">
            在 Github 上编辑此页！
        </a>
    </div>
</article>

<div class="sub-nav hiden-in-phone">
    <dl id="sub-nav">
        <dt>本文内容</dt>
        <dd v-for="(ele, index) in sub_nav">
           <a v-bind:href="ele.href">{{ ele.name }}</a>
        </dd>
    </dl>
</div> 
</div>

<footer>
    <div>
        <p>© Copyright 2017 Tencent All Rights Reserved</p>
        <p>Tencent 2017</p>
    </div>
</footer>


<script>
var vm = new Vue({
    el : '#container',
    data: {
        sub_nav : [ ]
    },
    created:function(){
        var obj = [];
        $("article h3").each(function(){
            obj.push({name :  $(this).find("a").attr("title") , href : "#"+$(this).attr("id") });
        });

        this.sub_nav = obj;       
    }
});

var isShow = false;
$("nav").on("click","#btn-menu" , function(){

    if(!isShow){
        
        if($(document).scrollTop() > $(".sidebar").height() - 100){

            $('html, body').animate({scrollTop:0} , 300, "swing",function(){

                $(".sidebar").fadeIn();
                $(".container").animate({"left" : "15rem"}, 500,"swing");
            });
        }else{

                $(".sidebar").fadeIn();
                $(".container").animate({"left" : "15rem"}, 500,"swing");

        }

    }else{
        $(".sidebar").fadeOut();
        $(".container").animate({"left" : "0rem"}, 500,"swing");
    }
    isShow = !isShow;

});

$(".container").on("click" , "article" , function(){

    if(isShow){
        $(".sidebar").fadeOut();
        $(".container").animate({"left" : "0rem"}, 500,"swing");
        isShow = false;    
    }

});
</script>
        
    </body>
</html>